/*
 * File:   MainMenu.cpp
 * Author: kojima
 *
 * Created on September 25, 2012, 5:21 PM
 */

#include "MainMenu.h"
#include <stdint.h>
#include <iostream>
#include <qt4/QtCore/qlist.h>
#include <qt4/QtCore/qstring.h>

//prototipi
void inserisciTesta (QString) ;
void inserisciCoda (QString) ;
void eliminaCoda () ;
void eliminaTesta () ;
void eliminaLista () ;
void aggiornaVideo () ;
uint32_t contaElementi () ;
void modificaPayloadDummy (bool) ;//blablabla
void aggiornaCasella () ;

/**Elemento lista: campo informazione e campo puntatore al successivo*/
struct elemento {
    /**campo informazione*/
    QString payload ;
    /**campo puntatore al prossimo elemento*/
    elemento * next ;
    /**campo puntatore al precedente elemento*/
    elemento * prev ;
} ;

elemento dummy ;
elemento * indiceElemento = NULL ;

MainMenu::MainMenu ()
{
    widget.setupUi (this) ;
    //    connect (widget.nostroBottone, SIGNAL (clicked ()), this, SLOT (cliccato ())) ;

    dummy.payload = "0" ; //numero elementi lista ;
    dummy.next = dummy.prev = NULL ;
    aggiornaVideo();
}

MainMenu::~MainMenu () { }

void MainMenu::on_nostroBottone_clicked ()
{
    QString str = widget.nostraTXT->text () ;
    QString tmp ;
    for (int32_t i = str.length () - 1 ; i >= 0 ; i--)
    {
        tmp.append (str.mid (i, 1)) ;
    }
    //    QString a, b, c ;
    //    b = "   " ;
    //    c = "pippo" ;
    //    a = a + b + c ;
    //    std::cout << a.toAscii ().data () << std::endl;
    widget.nostraTXT->setText (tmp) ;
}

void MainMenu::aggiornaVideo ()
{
    widget.listWidget->clear () ;
    aggiornaCasella () ;

    elemento *indice = dummy.next ;
    while (indice)
    {
        widget.listWidget->addItem (indice->payload) ;
        indice = indice->next ;
    }
    QString str = QString::number (contaElementi (), 10) ;
    widget.lblNumElementi->setText (str) ;
    widget.lblNumElementi2->setText (dummy.payload) ;

}

void MainMenu::aggiornaCasella ()
{
    if (!indiceElemento)
    {
        QFont mioFont = widget.lblElementoCorrente->font () ;
        mioFont.setBold (false) ;
        widget.lblElementoCorrente->setFont (mioFont) ;
        widget.lblElementoCorrente->setText ("~NULL~") ;
     }
    else
    {
        QFont mioFont = widget.lblElementoCorrente->font () ;
        mioFont.setBold (true) ;
        widget.lblElementoCorrente->setFont (mioFont) ;
        widget.lblElementoCorrente->setText (indiceElemento->payload) ;
//        std::cout<<"#" <<indiceElemento->payload.toAscii ().data ()<<"#"<<std::endl;
    }
    elemento * i = &dummy ;
    while (i->next) // ci posiziona all'ultimo elemento ;
        i = i->next ;

//    if ((dummy.next) && (indiceElemento != i))//se indiceElemento è diverso dalla coda
        widget.btnNext->setEnabled ((dummy.next) && (indiceElemento != i)) ;
//    else
//        widget.btnNext->setEnabled (false) ;

//    if (indiceElemento != dummy.next) //se indiceElemento non punta alla testa
        widget.btnPrev->setEnabled (indiceElemento != dummy.next) ;
//    else
//        widget.btnPrev->setEnabled (false) ;

}

void MainMenu::on_btnInserisciTesta_clicked ()
{
    QString input = widget.input->text () ;
    inserisciTesta (input) ;
    aggiornaVideo () ;
}

void MainMenu::on_btnInserisciCoda_clicked ()
{
    QString input = widget.input->text () ;
    inserisciCoda (input) ;
    aggiornaVideo () ;
}

void MainMenu::on_btnEliminaTesta_clicked ()
{
    eliminaTesta () ;
    aggiornaVideo () ;
}

void MainMenu::on_btnEliminaCoda_clicked ()
{
    eliminaCoda () ;
    aggiornaVideo () ;
}

void MainMenu::on_btnEliminaLista_clicked ()
{
    eliminaLista () ;
    aggiornaVideo () ;
}

void inserisciTesta (QString inf)
{
    elemento * tmp = new elemento ;
    tmp->payload = inf ;
    tmp->next = dummy.next ;
    tmp->prev = NULL ;
    if (!dummy.next) //stiamo inserendo su lista vuota
        indiceElemento = tmp ;
    else
        tmp->next->prev = tmp ;
    dummy.next = tmp ;
    modificaPayloadDummy (true) ;
}

void inserisciCoda (QString inf)
{
   elemento * i = &dummy ;
  while (i->next) // ci posiziona all'ultimo elemento
        i = i->next ;
  
  elemento * tmp = new elemento ;
  i->next = tmp ;
  i->next->payload = inf ;
  i->next->next = NULL ;
  
  if (!dummy.next) // se era vuoto
    {
      indiceElemento = tmp ;
      i->next->prev = NULL ;
    }
    else
      i->next->prev = i ;
    modificaPayloadDummy (true) ;
}

void eliminaTesta ()
{
    if (!dummy.next)
        return ;
    elemento * tmp = NULL ;

    if (dummy.next->next)
    {
        tmp = dummy.next->next ;
        tmp->prev = &dummy ;
    }
    delete dummy.next ;
    dummy.next = tmp ;
    indiceElemento = dummy.next ;
    modificaPayloadDummy (false) ;
}

void eliminaCoda ()
{
    if (!dummy.next) //se la lista è vuota ;
        return ;

    /**i = indice che scansiona un elemento alla volta*/
    elemento *i = NULL ;
    i = &dummy ;

    while (i->next)
    {
        if (!i->next->next) //se l'elemento dopo è l'ultimo ;
        {
            delete i->next ; //cancellalo ;
            i->next = NULL ;
            indiceElemento = (i == &dummy) ? NULL : i ;
        }
        else //altrimenti se l'elemento dopo non è ancora l'ultimo ;
            i = i->next ; //incrementa ;
    }
    modificaPayloadDummy (false) ;
}

void eliminaLista ()
{
    if (!dummy.next) //se non ci sono elementi
        return ;

    elemento * i = dummy.next ; //indice
    dummy.next = NULL ; //scollego

    do
    {
        elemento * tmp = i->next ;
        delete i ;
        i = tmp ; //incremento l'indice ;
    }
    while (i) ;
    dummy.payload = "0" ;
    indiceElemento = NULL ;
}

uint32_t contaElementi ()
{
    uint32_t cont = 0 ;
    elemento * i = &dummy ;

    while (i->next)
    {
        i = i->next ;
        cont++ ;
    }
    return cont ;
}

void modificaPayloadDummy (bool b)
{
    bool ok ;
    uint32_t t = dummy.payload.toUInt (&ok, 10) ;
    dummy.payload = QString::number (b ? ++t : --t, 10) ;
}

void MainMenu::on_btnNext_clicked ()
{
    if (indiceElemento->next)
        indiceElemento = indiceElemento->next ;
    aggiornaCasella () ;
}

void MainMenu::on_btnPrev_clicked ()
{
    if (indiceElemento->prev != &dummy)
        indiceElemento = indiceElemento->prev ;
    aggiornaCasella () ;
}